/**
 * @file EcomAdminBean.java
 * Projet eCOM 2010 (Miage Descartes)
 * @author Doido Sébastien
 * @version 2
 * @brief Bean relatif au traitement des opérations réalisables par l'administrateur
 */
package ecom.beans;

import java.util.Collection;
import javax.ejb.Stateful;
import javax.persistence.NoResultException;
import javax.persistence.Query;

/**
 * @brief Bean relatif au traitement des opérations réalisables par l'administrateur
 * @author Sebastien
 */
@Stateful
public class EcomAdminBean extends EcomCommonFunctionsBean implements EcomAdminRemote {

    /**
     * @brief Creation d'une catégorie de produit
     * @param categoryName : nom de la catégorie
     * @return l'identifiant affecté à la catégorie
     */
    public int createProductCategory(String categoryName) {
        System.out.println("creating category with auto id");
        CategoryBean cat = new CategoryBean(categoryName);
        em.persist(cat);
        return cat.getIdCateg();
    }

    /**
     * @brief Creation d'un nouveau produit
     * @param productName : nom du produit
     * @param description : description du produit
     * @param categoryId : catégorie du produit
     * @return  l'identifiant affecté au produit
     * @throws ecom.beans.UnknownIdentifier : exception levée si catégorie inexistante
     */
    public int createProduct(String productName, String description, int categoryId) throws UnknownIdentifier {
        System.out.println("creating product with auto id");

        CategoryBean categ = this.getCategoryById(categoryId);

        ProductBean myProduct = new ProductBean(productName, description, categ);
        em.persist(myProduct);
        return myProduct.getProductId();
    }

    /**
     * @brief Creation d'un nouveau magasin de produits
     * @param productStoreAccountId : compte affecté au magasin
     * @param productStoreName : nom du magasin
     * @param city : ville du magasin
     * @return l'identifiant affecté au magasin
     * @throws ecom.beans.UnknownIdentifier
     */
    public int createProductStore(int productStoreAccountId, String productStoreName, String city) throws UnknownIdentifier {
        System.out.println("creating product store with auto id");

        AccountBean account = getAccountById(productStoreAccountId);

        ProductStoreBean myStore = new ProductStoreBean(account, productStoreName, city);
        em.persist(myStore);
        return myStore.getReference();
    }

    /**
     * @brief Creation d'une ligne d'inventaire (stock)
     * @param productStoreId : référence du magasin
     * @param productId : référence du produit
     * @param quantity : quantité disponible
     * @param price : prix de vente
     * @return l'identifiant affecté à la ligne de stock
     * @throws ecom.beans.UnknownIdentifier : exception levée si produit|magasin inexistant
     */
    public int createStockLine(int productStoreId, int productId, int quantity, double price) throws UnknownIdentifier {
        System.out.println("creating stock line with auto id");

        ProductStoreBean store = getStoreById(productStoreId);
        ProductBean product = getProductById(productId);

        Query stockList = em.createNamedQuery("getStockByProductAndStore");
        stockList.setParameter("productID", product.getProductId());
        stockList.setParameter("productStoreID", store.getReference());

        WarehouseLineBean myStock = null;
        try {
            myStock = (WarehouseLineBean) stockList.getSingleResult();
            myStock.setQuantity(myStock.getQuantity() + quantity);
            myStock.setProductPrice(price);
        } catch (NoResultException e) {
            System.out.println("new stockline");
            myStock = new WarehouseLineBean(store, product, quantity, price);
        }
        em.persist(myStock);
        return myStock.getIdLine();
    }

    
    /**
     * @brief Mise à jour d'une catégorie
     * @param categoryId : id de la catégorie à modifier
     * @param categoryName : nouveau nom
     * @throws ecom.beans.UnknownIdentifier : exception levée lorsque catégorie inexistante
     */
    public void updateProductCategory(int categoryId, String categoryName) throws UnknownIdentifier {
        CategoryBean categ = this.getCategoryById(categoryId);
        categ.setName(categoryName);
        em.persist(categ);
    }

    /**
     * @brief Mise à jour d'un produit
     * @param productId : produit à modifier
     * @param productName : nom du produit
     * @param description : description du produit
     * @param categoryId : catégorie du produit
     * @return  l'identifiant affecté au produit
     * @throws ecom.beans.UnknownIdentifier : exception levée si produit ou catégorie inexistante
     */
    public void updateProduct(int productId, String productName, String description, int categoryId) throws UnknownIdentifier {
        ProductBean product = this.getProductById(productId);
        product.setProductName(productName);
        product.setDescription(description);
        product.setCategory(getCategoryById(categoryId));
        em.persist(product);
    }

    /**
     * @brief Mise à jour d'un magasin de produits
     * @param storeId : magasin à modifier
     * @param productStoreAccountId : compte affecté au magasin
     * @param productStoreName : nom du magasin
     * @param city : ville du magasin
     * @return l'identifiant affecté au magasin
     * @throws ecom.beans.UnknownIdentifier : exception levée si magasin ou compte inexistant
     */
    public void updateProductStore(int storeId, int productStoreAccountId, String productStoreName, String city) throws UnknownIdentifier {
        ProductStoreBean store = this.getStoreById(storeId);
        store.setName(productStoreName);
        store.setCity(city);
        store.setAccount(this.getAccountById(productStoreAccountId));
        em.persist(store);
    }

    /**
     * @brief Suppression d'un compte
     * @param idAccount : référence du compte
     * @throws ecom.beans.UnknownIdentifier : exception levée si compte inexistant
     */
    public void removeAccount(int idAccount) throws UnknownIdentifier {
        AccountBean a = getAccountById(idAccount);
        em.remove(a);
    }

    /**
     * @brief Suppression d'une catégorie de produits
     * @param idCateg : id de la catégorie
     * @throws ecom.beans.UnknownIdentifier : exception levée si catégorie inexistante
     */
    public void removeCategory(int idCateg) throws UnknownIdentifier {
        CategoryBean categ = getCategoryById(idCateg);
        Collection<ProductBean> list = this.getProductsInCateg(idCateg);

        for (ProductBean p : list) {
            this.removeProduct(p.getProductId());
        }
        em.remove(categ);
    }

    /**
     * @brief Suppression d'un magasin
     * @param idProductStore : référence du magasin
     * @throws ecom.beans.UnknownIdentifier : exception levée si magasin inexistant
     */
    public void removeStore(int idProductStore) throws UnknownIdentifier {
        ProductStoreBean store = getStoreById(idProductStore);

        Collection<WarehouseLineBean> stocks = this.getProductsInStore(idProductStore);
        for (WarehouseLineBean w : stocks) {
            em.remove(w);
        }
        em.remove(store);
    }

    /**
     * @brief Suppression d'un produit
     * @param idProduct : référence du produit
     * @throws ecom.beans.UnknownIdentifier : exception levée si produit inexistant
     */
    public void removeProduct(int idProduct) throws UnknownIdentifier {
        ProductBean product = this.getProductById(idProduct);
        Collection<WarehouseLineBean> stocks = this.getProductsByProductId(idProduct);
        for (WarehouseLineBean w : stocks) {
            em.remove(w);
        }
        em.remove(product);
    }

    /**
     * @brief liste tous les comptes acheteurs/magasinc connus
     * @return les comptes acheteurs/magasinc connus
     */
    public Collection<AccountBean> getAllAccounts() {
        System.out.println("loading all accounts");
        return em.createNamedQuery("allAccounts").getResultList();
    }
}
